package com.yc.utils;

/**
 * @author zwei
 * @create 2024-05-16 16:45
 */
public class MyHashMap <K,V>{
    /**
     * map的底层就是一个Node数组  每个元素都是一个Node 如果这个元素的hash冲突 则这个node变为链表
     */
    private Node<K,V>[]table;
    //数组的初始大小
    private final int DEFAULT_INITIAL_CAPACITY=1<<4;    //1<<4  =1000  就是16

    private int size=0; //表示table中实际存的元素个数

    /**
     * 负载因子 ：减少生成链表的机会  因为table一旦存满了  则必须增加生成链表的机会
     * 所以在table还没有存满前  就要扩容
     */
    private static final float DEFAULT_FACTOR=0.75f;
    /**
     * 阈值：数组容量*负载因子
     */
    private int threshold;
    public MyHashMap(){
        table=new Node[DEFAULT_INITIAL_CAPACITY];
        threshold=(int) DEFAULT_FACTOR*table.length;
    }
    public int size(){
        return this.size;
    }

    /**
     * 根据key取值
     * @param k
     * @return
     */




    /**
     * //减少hash冲突   使生产的哈希码足够离散
     * 利用hash()来完成对key生成hashcode的操作
     * Object中原来就有hashCode(),key.hashCode()就已经生成了hsah码
     * a b c d e
     * 解决方案：1.先key.hashcode  2.hashcode是32位整数，将它的高低16位混洗  (^)
     * @param key
     * @return
     */
    static final int hash(Object key){
        int h=key.hashCode();
        return  (key==null)?0:(h^(h>>16));
    }

    /**
     * 计算Node[]数组中的索引
     * n:表示Node[]数组的长度  通常是2的幂次  -1：全为1
     *      n=8     n-1=7       111
     *      n=16    n-1=15      1111
     * @param n
     * @param key
     * @return
     */
    static int index(int n,Object key){
        //hash(key)%n;
        return (n-1)&hash(key);     //等同于求余数  此余数即为key在数组中的索引
    }


    /**
     *  项：相当于HashMap  中的Entry<k,v>
     * @param <k>
     * @param <v>
     */
    class Node<k,v>{
        int hash;   //此Node计算出来的hash值 用这个hash值可以找到在数组中的位置
        k k;     //键
        v v;    //值

        Node<k,v> next;

        public Node(int hash, k k, v v, Node<k, v> next) {
            this.hash = hash;
            this.k = k;
            this.v = v;
            this.next = next;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "hash=" + hash +
                    ", k=" + k +
                    ", v=" + v +
                    ", next=" + next +
                    '}';
        }

        public Node<k, v> getNext() {
            return next;
        }

        public void setNext(Node<k, v> next) {
            this.next = next;
        }

        public int getHash() {
            return hash;
        }

        public void setHash(int hash) {
            this.hash = hash;
        }

        public k getK() {
            return k;
        }

        public void setK(k k) {
            this.k = k;
        }

        public v getV() {
            return v;
        }

        public void setV(v v) {
            this.v = v;
        }
    }


}
